package top.deepdesigner.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.deepdesigner.mapper.DtsGoodsAttributeMapper;
import top.deepdesigner.mapper.DtsGoodsProductMapper;
import top.deepdesigner.mapper.DtsGoodsSpecificationMapper;
import top.deepdesigner.mapper.DtsOrderMapper;
import top.deepdesigner.pojo.DtsGoods;
import top.deepdesigner.pojo.DtsGoodsAttribute;
import top.deepdesigner.pojo.DtsGoodsProduct;
import top.deepdesigner.pojo.DtsGoodsSpecification;
import top.deepdesigner.service.DtsGoodsService;
import top.deepdesigner.vo.GoodsAllinone;
import top.deepdesigner.vo.StatGoodVO;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Start up <br/>
 * Created with IntelliJ IDEA. <br/>
 * Project Name: shop_manage <br/>
 * Author: duanruiqing <br/>
 * DateTime: 2022/9/20 星期二 20:21:30 <br/>
 */
@Service
public class DtsGoodsServiceImpl extends ServiceImpl<BaseMapper<DtsGoods>, DtsGoods> implements DtsGoodsService {

  @Autowired
  private DtsGoodsAttributeMapper goodsAttributeMapper;
  @Autowired
  private DtsGoodsSpecificationMapper goodsSpecificationMapper;
  @Autowired
  private DtsGoodsProductMapper goodsProductMapper;

  @Autowired
  private DtsOrderMapper dtsOrderMapper;

  @Override
  public Long getGoodsCount() {
    return this.count(null);
  }

  @Override
  public DtsGoods getGoodsByGoodId(Long goodsId) {
    LambdaQueryWrapper<DtsGoods> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(DtsGoods::getId, goodsId);
    return this.getOne(wrapper);
  }

  @Override
  public List<StatGoodVO> getGoodsByDate(int days) {
    return dtsOrderMapper.selectOrderAndGoodsStat(days);
  }

  @Override
  public List<DtsGoods> getGoodsList(Integer page, Integer limit, String sort, String order, Integer goodsSn, String name) {
    QueryWrapper<DtsGoods> wrapper = new QueryWrapper<>();
    wrapper
        .eq("deleted", 0)
        .eq(goodsSn != null, "goods_sn", goodsSn)
        .like(!StringUtils.isEmpty(name), "name", name)
        .orderBy(true, "asc".equalsIgnoreCase(order), sort);
    return this.page(new Page<>(page, limit), wrapper).getRecords();
  }

  @Override
  public List<Integer> getGoodsCategoryByGoodId(Long id) {
    LambdaQueryWrapper<DtsGoods> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(DtsGoods::getId, id)
        .select(DtsGoods::getCategoryId);
    List<DtsGoods> list = this.list(wrapper);
    return list.stream().map(DtsGoods::getCategoryId).collect(Collectors.toList());
  }

  //更新Goods相关的所有信息
  @Override
  @Transactional
  public void updateGoods(GoodsAllinone<Integer> goods) {
    Integer goodsId = goods.getGoods().getId();
    //更新dts_goods
    this.update(goods.getGoods(), new LambdaUpdateWrapper<DtsGoods>()
        .eq(DtsGoods::getId, goodsId));
    //更新dts_goods_attribute
    goodsAttributeMapper.delete(new LambdaQueryWrapper<DtsGoodsAttribute>()
        .eq(true, DtsGoodsAttribute::getGoodsId, goodsId));
    if (goods.getAttributes().size() > 0) {
      for (int i = 0; i < goods.getAttributes().size(); i++) {
        DtsGoodsAttribute goodsAttribute = goods.getAttributes().get(i).setGoodsId(goodsId);
        goodsAttributeMapper.insert(goodsAttribute);
      }
    }
    //更新dts_goods_product
    goodsProductMapper.delete(new LambdaQueryWrapper<DtsGoodsProduct>()
        .eq(true, DtsGoodsProduct::getGoodsId, goodsId));
    if (goods.getProducts().size() > 0) {
      for (int i = 0; i < goods.getProducts().size(); i++) {
        DtsGoodsProduct dtsGoodsProduct = goods.getProducts().get(i).setGoodsId(goodsId);
        goodsProductMapper.insert(dtsGoodsProduct);
      }
    }

    //更新dts_goods_specification
    goodsSpecificationMapper.delete(new LambdaQueryWrapper<DtsGoodsSpecification>()
        .eq(true, DtsGoodsSpecification::getGoodsId, goodsId));
    if (goods.getSpecifications().size() > 0) {
      for (int i = 0; i < goods.getSpecifications().size(); i++) {
        DtsGoodsSpecification specification = goods.getSpecifications().get(i).setGoodsId(goodsId);
        goodsSpecificationMapper.insert(specification);
      }
    }
  }

  @Override
  @Transactional
  public void deleteGoods(Integer goodsId) {
    LambdaQueryWrapper<DtsGoods> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(DtsGoods::getId, goodsId);

    DtsGoods goods = new DtsGoods();
    goods.setDeleted(true);
    goods.setUpdateTime(new Date());
    this.update(goods, wrapper);
  }

  @Override
  @Transactional
  public Boolean createGoods(GoodsAllinone<Integer> goods) {
    List<DtsGoods> list = this.list(new LambdaQueryWrapper<DtsGoods>()
        .eq(true, DtsGoods::getGoodsSn, goods.getGoods().getGoodsSn())
        .eq(true, DtsGoods::getDeleted, false));
    if (list.size() > 0) {
      return false;
    }
    this.save(goods.getGoods());
    for (DtsGoodsProduct product : goods.getProducts()) {
      product.setGoodsId(goods.getGoods().getId());
      product.setAddTime(new Date());
      product.setUpdateTime(new Date());
      product.setDeleted(false);
      goodsProductMapper.insert(product);
    }
    for (DtsGoodsAttribute attribute : goods.getAttributes()) {
      attribute.setGoodsId(goods.getGoods().getId());
      attribute.setAddTime(new Date());
      attribute.setUpdateTime(new Date());
      attribute.setDeleted(false);
      goodsAttributeMapper.insert(attribute);
    }
    for (DtsGoodsSpecification specification : goods.getSpecifications()) {
      specification.setGoodsId(goods.getGoods().getId());
      specification.setAddTime(new Date());
      specification.setUpdateTime(new Date());
      specification.setDeleted(false);
      goodsSpecificationMapper.insert(specification);
    }
    return true;
  }
}
